#include "XMLHelper.h"
#include "math.h"

using namespace Utility;

XMLHelper* XMLHelper::currentInstance = NULL;
XMLHelper* XMLHelper::getInstance()
{
	if(XMLHelper::currentInstance == NULL)
	{
		currentInstance = new XMLHelper();
	}

	return currentInstance;
}
XMLHelper::~XMLHelper()
{
	delete currentInstance; 
}

XMLHelper::XMLHelper()
{
	XMLHelper::LinkRelationshipUri = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
	XMLHelper::ImageRelationshipUri = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
	
}

WordXmlPicture::WordXmlPicture()
{
	targetFrame = NULL;
	tooltip = NULL;
	hlinkRef = NULL;
	alt = NULL;
	id = NULL;
}

WordXmlPicture::~WordXmlPicture()
{};
//Read relationship details for the docx image and hyperlink parts
//should be part of transformation core
void XMLHelper::ReadRelationship(XercesDOMParser *parser, map<const XMLCh*, const XMLCh*> *rel_map, char* relationshipURI)
{
	xercesc::DOMDocument *doc = parser->getDocument();	
	DOMElement *node = NULL;
	DOMNamedNodeMap *nodelist = NULL;
	DOMElement *root = doc->getDocumentElement();
	XMLCh *relURI = XMLString::transcode(relationshipURI);
	DOMNode *tnode = NULL;

	
	DOMNodeIterator *nodeiterator = ((DOMDocumentTraversal*)doc)->createNodeIterator(root, DOMNodeFilter::SHOW_ELEMENT, 0, false);

	while((tnode = nodeiterator->nextNode()))
	{	
		XMLCh *typeval = GetAttributeValue(tnode->getAttributes(), "Type");
		
		if(XMLString::compareString(typeval, relURI) == 0)
		{	
			rel_map->insert(std::pair<const XMLCh*, const XMLCh*>(GetAttributeValue(tnode->getAttributes(), "Id"),
				GetAttributeValue(tnode->getAttributes(), "Target")));			
		}
	}

	XMLString::release(&relURI);
	nodeiterator->release();	
}

//Get named attribute value from node map
XMLCh* XMLHelper::GetAttributeValue(const DOMNamedNodeMap *attr_list, char *id)
{
	XMLCh *t_id = XMLString::transcode(id);
	DOMAttr *attr = NULL;
	XMLCh *retValue = NULL;
		
	for(XMLSize_t i = 0; i < attr_list->getLength(); i++)
	{
		attr = dynamic_cast<DOMAttr*>(attr_list->item(i));		
		
		int compareVal = XMLString::compareString(attr->getNodeName(), t_id); 		
		if(compareVal == 0)
		{			
			retValue = const_cast<XMLCh*>(attr->getNodeValue());			
			break;
		}	
	}		
	
	XMLString::release(&t_id);	
	return retValue;
}

XMLCh* XMLHelper::GetAttributeValue(DOMElement* element, char *id)
{
	XMLCh *id_x = XMLString::transcode(id);	
	return const_cast<XMLCh*>(element->getAttribute(id_x));
}

string XMLHelper::GetFromAttributeValue(const DOMNamedNodeMap *attr_list, char *from)
{	
	XMLCh *str = XMLString::transcode(from);

	string strObj = XMLHelper::convertToString(str);
	XMLString::release(&str);
	return strObj;

}

string XMLHelper::GetToAttributeValue(const DOMNamedNodeMap *attr_list, char *to)
{	
	XMLCh *str = XMLString::transcode(to);

	string strObj = XMLHelper::convertToString(str);
	XMLString::release(&str);
	return strObj;

}

//Select elements specified in xpath query
//Hint: Include root in the XPath query skip the root indicator (/) in the query
vector<DOMElement*>* XMLHelper::ParseMinimalXPath(xercesc::DOMDocument *doc, DOMElement *startNode, char *query)
{	
	DOMElement *root = dynamic_cast<DOMElement*>(startNode);

	bool startanywhere = false;
	DOMNodeList *list;
	vector<string> tokens;
	XMLCh *xmlstring = NULL;
	vector<DOMElement*> *masterlist;
	vector<DOMElement*> *templist;
	string temp;

	string strquery = query;	
	if(strquery.substr(0,2) == "//")
	{		
		temp = strquery.substr(2, strquery.length());
		query = strdup(temp.c_str());
		startanywhere = true;
	}

	StrTokenize(query, "/", &tokens);		
	vector<string>::iterator iter = tokens.begin();
	strquery = *iter;
	
	list = root->getElementsByTagName(XMLString::transcode(strquery.c_str()));

	if(tokens.size() == 1)
	{
		int lc = list->getLength();
		masterlist = new vector<DOMElement*>();
		for(int i = 0; i < lc; i++)
		{	
			root = dynamic_cast<DOMElement*>(list->item(i));
			masterlist->insert(masterlist->end(), root);						
		}
		return masterlist;
	}
		
	if(startanywhere)
	{
		masterlist = new vector<DOMElement*>();
				
		int listcount = list->getLength();
		for(int i = 0; i < listcount; i++)
		{	
			root = dynamic_cast<DOMElement*>(list->item(i));
			templist = GetXPathResults(doc, root, tokens);
			masterlist->insert(masterlist->end(), templist->begin(), templist->end());						
		}

		return masterlist;
	}
	else
	{
		return GetXPathResults(doc, root, tokens);
	}
}

//Select elements specified in xpath query starting from startNode
//Hint: Include root in the XPath query skip the root indicator (/) in the query
//vector<DOMElement*>* XMLHelper::GetXPathResults(xercesc::DOMDocument *doc, DOMNode *startNode, char *query)
//{
//	DOMElement *root = dynamic_cast<DOMElement*>(startNode);
//	DOMTreeWalker *treewalker = ((DOMDocumentTraversal*)doc)->createTreeWalker(root, DOMNodeFilter::SHOW_ELEMENT, 0, true);
//
//	string xpath = query;
//	DOMElement *node = NULL;
//	vector<string> tokens;	
//	vector<DOMElement*> *selectedElements = new vector<DOMElement*>();
//
//	//Tokenize path elements
//	StrTokenize(xpath, "/", &tokens);	
//
//	if(tokens.size() > 0)
//	{
//		//Node init
//		node = dynamic_cast<DOMElement*>(treewalker->getRoot());
//		GetElements(tokens, 0, treewalker, selectedElements);		
//	}
//
//	treewalker->release();
//	return selectedElements;
//}
vector<DOMElement*>* XMLHelper::GetXPathResults(xercesc::DOMDocument *doc, DOMNode *startNode, vector<string> tokens)
{
	DOMElement *root = dynamic_cast<DOMElement*>(startNode);
	DOMTreeWalker *treewalker = ((DOMDocumentTraversal*)doc)->createTreeWalker(root, DOMNodeFilter::SHOW_ELEMENT, 0, true);

	DOMElement *node = NULL;
	vector<DOMElement*> *selectedElements = new vector<DOMElement*>();

	if(tokens.size() > 0)
	{
		//Node init
		node = dynamic_cast<DOMElement*>(treewalker->getRoot());
		GetElements(tokens, 0, treewalker, selectedElements);		
	}

	treewalker->release();
	return selectedElements;
}

//Get xpath query results
void XMLHelper::GetElements(vector<string> tokens, int depth, DOMTreeWalker *walker, XMLHelper::XMLHelper_XPathResult *selectedElements)
{
	string tokenstr = tokens[depth];	
	int currentDepth = depth;
	DOMElement *node = dynamic_cast<DOMElement*>(walker->getCurrentNode());
	XMLCh *compareToken = XMLString::transcode(tokenstr.c_str()); 

	if(XMLString::compareString(node->getNodeName(), compareToken) == 0)
	{
		if(depth >= (int)(tokens.size()) - 1)
		{
			//This is the node that we need to select
			selectedElements->push_back(node);						
		}
		else
		{
			depth++;
			node = dynamic_cast<DOMElement*>(walker->firstChild());
			if(node != NULL)
			{
				GetElements(tokens, depth, walker, selectedElements);				
			}
			//unravel walker
			node = dynamic_cast<DOMElement*>(walker->parentNode());
		}
	}

	node = dynamic_cast<DOMElement*>(walker->nextSibling());

	while(node != NULL)
	{		
		GetElements(tokens, currentDepth, walker, selectedElements);		
		node = dynamic_cast<DOMElement*>(walker->nextSibling());
	}	

	XMLString::release(&compareToken);
}

void XMLHelper::StrTokenize(string str, string delimiter, vector<string> *tokens)
{
	int pos;
	while( (pos = str.find_first_of(delimiter)) != str.npos )
	{
		if(pos > 0)
		{
			tokens->push_back(str.substr(0, pos));
		}
		str = str.substr(pos + 1);
	}
	if(str.length() > 0)
	{
		tokens->push_back(str);
	}
}


void XMLHelper::PrintAttributes(const DOMNamedNodeMap *attr_list)
{
	for(XMLSize_t i = 0; i < attr_list->getLength(); i++)
	{
		wcout<<" "<<attr_list->item(i)->getNodeName()<<" = "<<attr_list->item(i)->getNodeValue();
	}
	wcout<<endl;
}

int XMLHelper::convertToInt(const std::string& s)
{
	std::istringstream stream(s);
	int x;
	stream >> x;     
	return x;
}
 float XMLHelper::convertToFloat(const std::string& s)
{
	std::istringstream stream(s);
	float x;
	stream >> x;     
	return x;
} 


 float XMLHelper::convertToFloat(const XMLCh* s_xml)
{
	char* s_char = XMLString::transcode(s_xml);
	string s = s_char;
	return convertToFloat(s);
}

char* XMLHelper::convertToString(const int i)
{
	std::stringstream out;
	out << i;
	return strdup(out.str().c_str());
}

int XMLHelper::convertToInt(const XMLCh* s_xml)
{
	char* s_char = XMLString::transcode(s_xml);
	string s = s_char;
	return convertToInt(s);
}

string XMLHelper::convertToString(const XMLCh *s_xml)
{
	char *s_char = XMLString::transcode(s_xml);
	return string(s_char);
}

string XMLHelper::convertToString( float f)
{
	std::stringstream out;
	out << f;	
	return out.str();
}

XMLCh* XMLHelper::convertToXMLCh(const string s)
{
	char *s_char = strdup(s.c_str());
	return XMLString::transcode(s_char);
}

XMLCh* XMLHelper::convertToXMLCh(const int i)
{
	string s = convertToString(i);	
	return convertToXMLCh(s);
}

DOMElement* XMLHelper::SelectSingleNode(xercesc::DOMDocument *doc, DOMElement *selectNode, char *query)
{	
	DOMElement *ret = NULL;

	vector<DOMElement*> *nodes = ParseMinimalXPath(doc, selectNode, query);
	vector<DOMElement*>::iterator iter = nodes->begin();
	if(nodes->size() > 0)
	{			
		ret = iter[0];
	}
	return ret;
}

XMLCh* XMLHelper::GetServerRelativePath(XMLCh *docLibPath, XMLCh *itemUrl)
{
//	XMLCh *ret;
	string itemUrl_s = convertToString(itemUrl);
	string docLibPath_s = convertToString(docLibPath);

	
	if((itemUrl_s.substr(0, 1) == "/") ||
		(itemUrl_s.size() > 7 && itemUrl_s.substr(0,7) == "http://") ||
		(itemUrl_s.size() > 8 && itemUrl_s.substr(0,8) == "https://"))
	{
                return itemUrl;
	}
    else
    {
		docLibPath_s.append(itemUrl_s);
		return convertToXMLCh(docLibPath_s);
	}
}

DOMElement* XMLHelper::CreateImageElement(xercesc::DOMDocument *document, WordXmlPicture* picture, string fixupPath)
{
	DOMElement *imageElement, *linkElement;

	if (document != NULL && picture != NULL)
	{		
		imageElement = document->createElement(XMLString::transcode("img"));

		imageElement->setAttribute(XMLString::transcode("xmlns"), XMLString::transcode("http://www.w3.org/1999/xhtml"));
		
		if (XMLString::stringLen(picture->id) > 0)
		{
			imageElement->setAttribute(XMLString::transcode("id"), picture->id);
		}
		else
		{
			string s = convertToString(rand());
			imageElement->setAttribute(XMLString::transcode("id"), convertToXMLCh(s));
		}
				
		if (XMLString::stringLen(picture->alt) > 0)
		{
			imageElement->setAttribute(XMLString::transcode("alt"), picture->alt);
		}

		if (XMLString::stringLen(picture->style) > 0)
		{
			imageElement->setAttribute(XMLString::transcode("style"), picture->style);
		}

		if (picture->widthSet)
		{
			imageElement->setAttribute(XMLString::transcode("width"), convertToXMLCh(picture->width));
		}

		
		if (picture->heightSet)
		{
			imageElement->setAttribute(XMLString::transcode("height"), convertToXMLCh(picture->height));
		}
		
		if (XMLString::stringLen(picture->src) > 0)
		{			
			imageElement->setAttribute(XMLString::transcode("src"), GetServerRelativePath(convertToXMLCh(fixupPath), picture->src));
		}
		
		if (XMLString::stringLen(picture->hlinkRef) > 0)
		{				
			linkElement = document->createElement(XMLString::transcode("a"));

			linkElement->setAttribute(XMLString::transcode("href"), picture->hlinkRef);

			if (XMLString::stringLen(picture->targetFrame) > 0)
			{
				linkElement->setAttribute(XMLString::transcode("target"), picture->targetFrame);
			}

			if (XMLString::stringLen(picture->tooltip) > 0)
			{
				linkElement->setAttribute(XMLString::transcode("title"), picture->tooltip);
			}

			linkElement->appendChild(imageElement);

			imageElement = linkElement;
		}				
		/*imageElement->setAttribute(XMLString::transcode("type"), XMLString::transcode("image/jpeg"));*/		
	}	

	return imageElement;
}

//Handle image in document
//should be part of transformation core
void XMLHelper::HandleImages(xercesc::DOMDocument *doc, map<const XMLCh*, const XMLCh*> imgMap, map<const XMLCh*, const XMLCh*> hyperlinkMap)
{
	if(imgMap.size() <= 0)
	{
		return;
	}	
	DOMElement *node = NULL;
	
	// handle E2.0 images
	vector<DOMElement*> *oartNodes = ParseMinimalXPath(doc, doc->getDocumentElement(), "//w:drawing/wp:inline");
	vector<DOMElement*> *templist = ParseMinimalXPath(doc, doc->getDocumentElement(), "//w:drawing/wp:anchor");
	oartNodes->insert(oartNodes->end(), templist->begin(), templist->end());
		
	vector<DOMElement*>::iterator oartNodeIter = oartNodes->begin();

	char *pictureDataXpathQuery = "//a:graphic/a:graphicData/pic:pic/pic:blipFill";
	
	for(XMLSize_t i = 0; i < oartNodes->size(); i++)
	{		
		node = oartNodeIter[i];
		
		DOMElement *pictureDataNode = SelectSingleNode(doc, node, pictureDataXpathQuery);
		
		if (pictureDataNode != NULL)
		{
			WordXmlPicture picture;

			picture.ReadStandardAttributes(pictureDataNode);

			DOMElement *picSizeNode = SelectSingleNode(doc, node, "//wp:extent");
			
			if (picSizeNode != NULL)
			{
				picture.ReadSizeAttributes(picSizeNode);
			}

			DOMElement *picLinkNode = SelectSingleNode(doc, node, "//wp:docPr/a:hlinkClick");

			if (picLinkNode != NULL)
			{
				XMLCh *linkRelId = GetAttributeValue(picLinkNode, "r:id");

				if (linkRelId != NULL && hyperlinkMap.size() > 0)
				{
					picture.hlinkRef = (XMLCh*)hyperlinkMap[linkRelId];
				}

				picture.ReadLinkAttributes(picLinkNode);
			}

			DOMElement *linkDataNode = SelectSingleNode(doc, pictureDataNode, "//a:blip");

			if (linkDataNode != NULL)
			{
				
				//Select Linked Images
				XMLCh *imgRelId = GetAttributeValue(linkDataNode, "r:link");
				XMLCh *imgEmbId = GetAttributeValue(linkDataNode, "r:embed");
				bool uselink = true;

				//if both link and embed tags are present, use embed
				if((XMLString::stringLen(imgRelId) > 0) && (XMLString::stringLen(imgEmbId) > 0))
				{
					uselink = false;
				}
			
				if (XMLString::stringLen(imgRelId) > 0 && imgMap.size() > 0 && uselink)
				{					
					map<const XMLCh*, const XMLCh*>::iterator it = imgMap.begin();
					for(int i = 0; i < imgMap.size(); i++)
					{							
						if(XMLString::compareString((XMLCh*)(it->first), imgRelId) == 0)
						{
							picture.src = (XMLCh*)it->second;
							break;
						}
						it++;
					}						
					//					wcout<<it->second<<endl;
					//					picture.src = (XMLCh*)imgMap[imgRelId];
				}
				else
				{					
					//Read embedded image link
					//imgRelId = GetAttributeValue(linkDataNode, "r:embed");

					if (XMLString::stringLen(imgEmbId) > 0 && imgMap.size() > 0)
					{
						string data = "word/";						
						map<const XMLCh*, const XMLCh*>::iterator it = imgMap.begin();
						XMLCh *img = NULL;
						
						for(int i = 0; i < imgMap.size(); i++)
						{							
							if(XMLString::compareString((XMLCh*)(it->first), imgEmbId) == 0)
							{
								img = (XMLCh*)it->second;
								break;
							}
							it++;
						}						
						
						if (img == NULL)
						{
							continue;
						}

						char *img_ch = strdup(XMLString::transcode(img));			

						if(img_ch == NULL)
						{
							continue;
						}
						data.append(img_ch);
						
						picture.src = convertToXMLCh(data);
						picture.hlinkRef = NULL;						
					}
				}			
			}

			DOMElement *imageElement = CreateImageElement(doc, &picture, "");
			
			if (imageElement != NULL)
			{
				node->getParentNode()->getParentNode()->replaceChild(imageElement, node->getParentNode());
			}
		}
	}


	// handle E1.0 images
	vector<DOMElement*> *nodes = ParseMinimalXPath(doc, doc->getDocumentElement(), "//w:pict");
	vector<DOMElement*> *t_nodes = ParseMinimalXPath(doc, doc->getDocumentElement(), "//w:object");
	nodes->insert(nodes->end(), t_nodes->begin(), t_nodes->end());

	vector<DOMElement*>::iterator iter = nodes->begin();

	//CONTINUE
	char *shapeXpathQuery = "//v:shape";
	DOMElement *inode = NULL;
	DOMElement *shapeNode = NULL;
	DOMElement *fillNode = NULL;
	DOMElement *imageDataNode = NULL;
	DOMElement *imageElement = NULL;

	for(XMLSize_t i = 0; i < nodes->size(); i++)
	{
		inode  = iter[i];
	
		fillNode = SelectSingleNode(doc, inode, "//v:fill");

		// handling v:fill in w:pict
		if(fillNode != NULL)
		{
			if(GetAttributeValue(fillNode, "r:id") != NULL)
			{				
				const XMLCh *imgaddr = NULL;				

				map<const XMLCh*, const XMLCh*>::iterator iter = imgMap.begin();

				while (iter != imgMap.end())	
				{ 					
					if (XMLString::compareString((iter->first), GetAttributeValue(fillNode, "r:id")) == 0)
					{
						imgaddr = iter->second;
						break;
					}
					iter++;
				}
				string src = "word/";
				if(imgaddr != NULL)
				{
					src  = src.append(convertToString(imgaddr));
				}				
				fillNode->setAttribute(XMLString::transcode("src"), convertToXMLCh(src));
			}
		}

		//handling v:imagedata present in v:shape
		shapeNode = SelectSingleNode(doc, inode, shapeXpathQuery);

		if (shapeNode != NULL)
		{
			WordXmlPicture picture;

			picture.ReadStandardAttributes(shapeNode);

			imageDataNode = SelectSingleNode(doc, shapeNode, "//v:imagedata");
			
			if (imageDataNode != NULL)
			{
				XMLCh *imgRelId = GetAttributeValue(imageDataNode, "r:id");

				string data = "word/";						
				map<const XMLCh*, const XMLCh*>::iterator it = imgMap.begin();
				XMLCh *img = NULL;
				
				for(int i = 0; i < imgMap.size(); i++)
				{							
					if(XMLString::compareString((XMLCh*)(it->first), imgRelId) == 0)
					{
						img = (XMLCh*)it->second;
						break;
					}
					it++;
				}	

				if (img == NULL)
				{
					continue;
				}

				char *img_ch = strdup(XMLString::transcode(img));						

				if(img_ch == NULL)
				{
					continue;
				}
				data.append(img_ch);
				
				picture.src = convertToXMLCh(data);
				
				// if the relationship isn't found, produce a warning
				//if (String.IsNullOrEmpty(picture.Src))
				//{
				//    embeddedPicturesDropped++;
				//}
				picture.hlinkRef = GetAttributeValue(imageDataNode, "href");

				imageElement = CreateImageElement(doc, &picture, "");
			}			
			
			if (imageElement != NULL)
			{
				inode->getParentNode()->replaceChild(imageElement, inode);
			}
		}
	}
}

void XMLHelper::HandleThemeFonts(xercesc::DOMDocument *mainDoc)
{
	//
	// Add theme style to run info 
	//
	vector<DOMElement*> *runNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:r");
	vector<DOMElement*>::iterator iter = runNodes->begin();
	DOMElement *runNode = NULL;
	DOMElement *runTextNode = NULL;
	string text;
	DOMAttr *classificationAttr;
	const XMLCh* textClass = XMLString::transcode("textClass");

	
	while(iter != runNodes->end())
	{
		runNode = *iter;

		runTextNode = SelectSingleNode(mainDoc, runNode, "//w:t");

		//Based on the runTextNode value, set the MsWordLanguageClassification. This was always set to hAnsiTest.
		//text  = runTextNode.InnerText()
		string textClassification = getMsWordLanguageClassification(text);

		// Add text classification as a hint to the run
		classificationAttr = mainDoc->createAttribute(textClass);
		classificationAttr->setValue(convertToXMLCh(textClassification));

		runNode->setAttributeNode(classificationAttr);			 

		iter++;
	}
}

// Module added for handling columns
// Module added for handling columns
// Module added for handling columns
void XMLHelper::HandleColumns(xercesc::DOMDocument *mainDoc){
	vector<DOMElement*> *sectNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:sectPr");
//	vector<DOMElement*> *multipleSectNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:p/w:pPr/w:sectPr/w:cols");
	vector<DOMElement*> *multipleSectNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:sectPr/w:cols");
	vector<DOMElement*>::iterator iter = sectNodes->begin();
	DOMElement * colsNode = NULL;
	DOMElement *sectNode = NULL;
	DOMElement *sectColumnNode = NULL;
	DOMElement *multiSectNode = NULL;
	if( multipleSectNodes->size() > 0)
	{
		vector<DOMElement*> *paraNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:p");
		vector<DOMElement*>::iterator paraIter = paraNodes->begin();
		DOMElement * pPrNode = NULL;
		DOMElement * paraNode = NULL;
		int sectNumber = 1;
		for(int j=0; j < paraNodes->size(); j++){
			paraNode = paraIter[j];
			pPrNode = SelectSingleNode(mainDoc, paraNode, "//w:pPr");
			if(pPrNode != NULL)
			{
				sectNumber = sectNumber + 1;
			}
			else
			{
				paraNode->setAttribute(convertToXMLCh("sectNum"),convertToXMLCh(sectNumber));
			}
		}
		vector<DOMElement*>::iterator sectColumnIter = multipleSectNodes->begin();
		int k = 0;
		int colCount = 1;
		int colNumber1;
		bool sectEnd = false;
		for(int j=0;j<paraNodes->size();j++)
		{
			if( k != -1)
			{
				sectColumnNode = sectColumnIter[k];             
				if(sectColumnNode->getAttributeNode(convertToXMLCh("w:num")) == NULL)
				{
					colNumber1 = 1;
				}
				else
				{
					colNumber1 = convertToInt(GetAttributeValue(sectColumnNode,"w:num"));
				}
			}
			else
			{
				colNumber1 = 1;
			}
			//int colNumber1 = 1;
			paraNode = paraIter[j];
			pPrNode = SelectSingleNode(mainDoc, paraNode, "//w:pPr/w:sectPr");
			if(pPrNode != NULL)
			{
				//sectNumber = sectNumber + 1;
				if(k < (multipleSectNodes->size()-1)){
					k++;
				}
				else
					k = -1;

				sectEnd = true;
				//break;
			}
			else
			{
				vector<DOMElement*> *lRPBNodes = ParseMinimalXPath(mainDoc, paraNode, "//w:r/w:lastRenderedPageBreak");
				vector<DOMElement*>::iterator iter1 = lRPBNodes->begin();
				DOMElement *lRPBNode = NULL;
				if(k == (multipleSectNodes->size())&& sectEnd == true){
					colNumber1 = 1;
				}
				for( int j=0;j<lRPBNodes->size();j++)
				{
					lRPBNode = iter1[j];
					lRPBNode->setAttribute(convertToXMLCh("colNum"),convertToXMLCh(colNumber1));
					lRPBNode->setAttribute(convertToXMLCh("colCount"),convertToXMLCh(colCount));
					if(colCount == colNumber1 || sectEnd == true)
					{   
						// Mark New Page
						lRPBNode->setAttribute(convertToXMLCh("pageNum"),convertToXMLCh(colCount));
						colCount = 1;
						if(sectEnd == true){                                        
							sectEnd = false;                                            
						}
					}
					else
					{
						colCount++;
					}
				}


			}
			colNumber1 =1;
		}     

	}
	else
	{
		int colNumber = 0;
		XMLCh * colNum = NULL;
		//string columnPath = "//w:sectPr/";
		for(int i=0; i < sectNodes->size(); i++)
		{
			sectNode = iter[i];
			colsNode = SelectSingleNode(mainDoc, sectNode, "//w:cols");
			if(colsNode != NULL){
				colNum = GetAttributeValue(colsNode,"w:num");
				if(XMLString::compareString(convertToXMLCh(""),colNum) != 0)
					colNumber = convertToInt(colNum);		
			}
			//cout<<colNumber;
		}
		vector<DOMElement*> *lRPBNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:r/w:lastRenderedPageBreak");
		vector<DOMElement*>::iterator iter1 = lRPBNodes->begin();
		DOMElement *lRPBNode = NULL;
		int colCount = 1;
		if (colNumber > 0){
			//colNumber = 1;        

			for( int j=0;j<lRPBNodes->size();j++){
				lRPBNode = iter1[j];
				lRPBNode->setAttribute(convertToXMLCh("colNum"),convertToXMLCh(colNumber));
				lRPBNode->setAttribute(convertToXMLCh("colCount"),convertToXMLCh(colCount));
				if(colCount == colNumber)
				{   
					// Mark New Page
					lRPBNode->setAttribute(convertToXMLCh("pageNum"),convertToXMLCh(colCount));
					colCount = 1;
				}
				else
				{
					colCount++;
				}
			}
			if((colCount < colNumber) && (lRPBNode != NULL))
			{
				lRPBNode->setAttribute(convertToXMLCh("ColumnEnd"),convertToXMLCh((colNumber-colCount+1)));              
			}
		}
	}
}

void XMLHelper::HandleCoverPage(xercesc::DOMDocument *mainDoc){
	//DOMElement *sdtnode = SelectSingleNode(mainDoc, mainDoc->getDocumentElement(), "//w:body/w:sdt/w:sdtContent");
	DOMElement *sdtnode = SelectSingleNode(mainDoc, mainDoc->getDocumentElement(), "//w:sdt/w:sdtContent");
	if(sdtnode != NULL){
		DOMElement *lRPBNode = SelectSingleNode(mainDoc, mainDoc->getDocumentElement(), "//w:r/w:lastRenderedPageBreak");
		if(lRPBNode != NULL){
		lRPBNode->setAttribute(convertToXMLCh("Coverpage"),convertToXMLCh("yes"));
		lRPBNode->setAttribute(convertToXMLCh("colNum"),convertToXMLCh("1"));
		lRPBNode->setAttribute(convertToXMLCh("pageNum"),convertToXMLCh("1"));
		}
	}
}
void XMLHelper::HandleTabIndentation(xercesc::DOMDocument *mainDoc)
{
	//vector<DOMElement*> *pNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:body/w:p");
	vector<DOMElement*> *pNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:p");
	vector<DOMElement*>::iterator iter = pNodes->begin();
	DOMElement *pnode = NULL;
	DOMElement *tabsnode = NULL;
	DOMElement *rtabnode = NULL;
	XMLCh *tabval = NULL;
	XMLCh *tabpos = NULL;
	DOMAttr *tabposAttr = NULL;
	DOMAttr *tabvalAttr = NULL;
	for(int i=0; i < pNodes->size(); i++){
		pnode = iter[i];
		tabsnode = SelectSingleNode(mainDoc, pnode, "//w:pPr/w:tabs");
		if(tabsnode != NULL){
			DOMElement * tabNode = SelectSingleNode(mainDoc, tabsnode, "//w:tab");
			tabpos = GetAttributeValue(tabNode, "w:pos");
			tabval = GetAttributeValue(tabNode, "w:val");
			rtabnode = SelectSingleNode(mainDoc, pnode, "//w:r/w:tab");
			if(rtabnode != NULL){
			tabposAttr = mainDoc->createAttribute(XMLString::transcode("w:pos"));
			tabposAttr->setValue(tabpos);
			rtabnode->setAttributeNode(tabposAttr);
			tabvalAttr = mainDoc->createAttribute(XMLString::transcode("w:val"));
			tabvalAttr->setValue(tabval);
			rtabnode->setAttributeNode(tabvalAttr);
			}
		}
	}

}

void XMLHelper::HandleLinks(xercesc::DOMDocument *mainDoc, map<const XMLCh*, const XMLCh*> hyperlinkTable)
{	
	// put the hyperlinks in places
	if (hyperlinkTable.size() <= 0)
	{		
		return;		
	}
	
	vector<DOMElement*> *linkNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement() ,"//w:hyperlink");
	vector<DOMElement*>::iterator iter = linkNodes->begin();
	DOMElement *node = NULL;
	DOMAttr *linkAttr = NULL;
	XMLCh *linkRelationShipId;
	XMLCh *srcDocLibPath = XMLString::transcode("");
	DOMElement *hlinkNode = NULL;
	
	for(int i=0; i < linkNodes->size(); i++)
	{		
		node = iter[i];

		// need to convert these three attributes
		
			linkRelationShipId = GetAttributeValue(node, "r:id");

			linkAttr = mainDoc->createAttribute(XMLString::transcode("w:dest"));
			
			XMLCh *link = NULL;// = (XMLCh*)hyperlinkTable[linkRelationShipId];
			map<const XMLCh*,const XMLCh*>::iterator hyperit = hyperlinkTable.begin();

			for(int i = 0; i < hyperlinkTable.size(); i++)
			{
				if(XMLString::compareString(hyperit->first, linkRelationShipId) == 0)
				{
					link = (XMLCh*)(hyperit->second);
					break;
				}
				hyperit++;
			}
		
			linkAttr->setValue(link);			

			if (linkAttr->getValue() != NULL && link != NULL)
			{
				srcDocLibPath = GetServerRelativePath(srcDocLibPath, const_cast<XMLCh*>(linkAttr->getValue()));
				
				linkAttr->setValue(srcDocLibPath);

				hlinkNode = mainDoc->createElement(XMLString::transcode("w:hlink"));

				hlinkNode->setAttributeNode(linkAttr);

			// copy the other attributes (such as target, tooltip, ...)
			DOMNamedNodeMap *attr_map = node->getAttributes();
			DOMAttr *node_attr = NULL;
			for(XMLSize_t j = 0; j < attr_map->getLength(); j++)
			{
				node_attr = dynamic_cast<DOMAttr*>(attr_map->item(j));
				hlinkNode->setAttributeNode(dynamic_cast<DOMAttr*>(node_attr->cloneNode(true)));
			}

			hlinkNode->appendChild(node->getFirstChild());

			DOMNodeList *hlink_list = node->getChildNodes(); 
			node->getParentNode()->replaceChild(hlinkNode, node);
			const  XMLSize_t nodeCount = hlink_list->getLength();
			int count = nodeCount;
			while(count > 0){
				DOMNode *child_Node= hlink_list->item(0);
				hlinkNode->appendChild((child_Node));
				//node->getParentNode()->replaceChild(hlinkNode, node);
				count-- ;
			}

		}     
	}
}


/// <summary>
/// count occurrences of numbered lists, save that as a hint on the numbered list node
/// </summary>
void XMLHelper::HandleNumberedLists(xercesc::DOMDocument *mainDoc)
{
	// count the number of different list numbering schemes
	//vector<DOMElement *> *numberNodes =  ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "w:document/w:numbering/w:num");
	vector<DOMElement *> *numberNodes =  ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:numbering/w:num");

	if (numberNodes->size() == 0)
	{		
		return;
	}
	
	// initialize the abstract number list
	vector<DOMElement*> *abstractNumNodes =  ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:numbering/w:abstractNum");
	vector<DOMElement*>::iterator absNumNodeIter = abstractNumNodes->begin();
	DOMElement* abstractNumNode = NULL;
	vector<DOMElement*> *linkedStyleNodes = NULL;
	DOMElement *numberNode = NULL;

	map<XMLCh*, AbstractListNumberingDefinition> abstractListDefinitions;
	map<XMLCh*, AbstractListNumberingDefinition>::iterator absListDefIter;
	map<XMLCh*, ListNumberingDefinition> instanceListDefinitions;
	XMLCh *linkStyleId = NULL;
	char *ValAttrName = "w:val";

	// store the abstract list type definitions
	for(XMLSize_t i = 0; i < abstractNumNodes->size(); i++)
	{		
		abstractNumNode = absNumNodeIter[i];
		AbstractListNumberingDefinition absNumDef(mainDoc, abstractNumNode);
		
		abstractListDefinitions[absNumDef.abstractNumDefId] = absNumDef;
	}
	
	// now go through the abstract list definitions and update those that are linked to other styles
	for(absListDefIter = abstractListDefinitions.begin(); absListDefIter!= abstractListDefinitions.end(); absListDefIter++)
	{		
		linkStyleId = absListDefIter->second.linkedStyleId;
		if(linkStyleId != NULL)
		{
			// find the linked style
			char* linkStyleXPath = "//w:numbering/w:abstractNum/w:styleLink";
			linkedStyleNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), linkStyleXPath);
			
			//string linkStyleXPath = "/w:document/w:numbering/w:abstractNum/w:styleLink[@w:val=\"" + absListDefIter->second.linkedStyleId + "\"]";
			if(linkedStyleNodes->size() > 0)
			{				
				vector<DOMElement*>::iterator linkStyleNodeIter = linkedStyleNodes->begin();
				
				for(XMLSize_t linkNodeCount = 0; linkNodeCount < linkedStyleNodes->size(); linkNodeCount++)
				{

					DOMElement* node_t = linkStyleNodeIter[linkNodeCount];
					XMLCh *attr = GetAttributeValue(node_t, "w:val");

					if(XMLString::compareString(linkStyleId, attr) == 0)
					{
						absListDefIter->second.UpdateDefinitionFromLinkedStyle(mainDoc, node_t);
						break;
					}
				}
			}
		}
	}	

	vector<DOMElement*>::iterator numberNodeIter = numberNodes->begin();

	// instantiate the list number definitions
	for(XMLSize_t i = 0; i < numberNodes->size(); i++)
	{		
		numberNode = numberNodeIter[i];
		ListNumberingDefinition listDef(mainDoc, numberNode, abstractListDefinitions);
		instanceListDefinitions[listDef.listNumberId] = listDef;
	}

	vector<DOMElement*> *listNodes = ParseMinimalXPath(mainDoc, mainDoc->getDocumentElement(), "//w:numPr/w:ilvl");
	vector<DOMElement*>::iterator listNodeIter = listNodes->begin();
	DOMElement *node = NULL;

	for(XMLSize_t i = 0; i < listNodes->size(); i++)
	{
		node = listNodeIter[i];
	
		XMLCh *levelId = GetAttributeValue(node, ValAttrName);
		DOMElement *parentNode = dynamic_cast<DOMElement*>(node->getParentNode());		
		DOMElement *numIdNode = dynamic_cast<DOMElement*>(parentNode->getLastChild());
		
//		DOMElement *numIdNode = SelectSingleNode(mainDoc, dynamic_cast<DOMElement*>(node->getParentNode()), "w:numId");

		if (levelId != NULL && numIdNode != NULL)
		{			
			XMLCh *numId = GetAttributeValue(numIdNode, ValAttrName);

			ListNumberingDefinition *listnumbering = &instanceListDefinitions[numId];

			if (numId != NULL &&  listnumbering != NULL 
				&& listnumbering->LevelExists(levelId))
			{
/*				DOMAttr *counterAttr = mainDoc->createAttribute(XMLString::transcode("numString"));

				instanceListDefinitions[numId].IncrementCounter(levelId);
				counterAttr->setValue(instanceListDefinitions[numId].GetCurrentNumberString(levelId));

				node->setAttributeNode(counterAttr);

				XMLCh *font = instanceListDefinitions[numId].GetFont(levelId);

				if (font != NULL)
				{
					DOMAttr *fontAttr = mainDoc->createAttribute(XMLString::transcode("numFont"));

					fontAttr->setValue(font);

					node->setAttributeNode(fontAttr);
				}
*/
				if (instanceListDefinitions[numId].IsBullet(levelId))
				{
					DOMAttr *bulletAttr = mainDoc->createAttribute(XMLString::transcode("isBullet"));

					bulletAttr->setValue(XMLString::transcode("true"));

					node->setAttributeNode(bulletAttr);
				}
			}
		}
	}

}

const string AsciiText = "asciiText";
const string HAnsiText = "hAnsiText";
const string EAText = "eaText";
const string CSText = "csText";


string XMLHelper::getMsWordLanguageClassification(string textRun)
{
    return HAnsiText;
}



void ListLevel::ResetCounter()
{
	counter = startValue;
}

void ListLevel::ListLevelIncrementCounter()
{
	counter++;
}

ListLevel::ListLevel()
{
}

ListLevel::ListLevel(xercesc::DOMDocument *doc, DOMElement *levelNode)
{
	XMLHelper *helper = XMLHelper::getInstance();

	char* ValAttrName = "w:val";
	id = helper->GetAttributeValue(levelNode, "w:ilvl");

	DOMElement *startValueNode = helper->SelectSingleNode(doc, levelNode, "//w:start");

	if (startValueNode != NULL)
	{
		XMLCh *startValueX = helper->GetAttributeValue(startValueNode, ValAttrName);
		char *startval = XMLString::transcode(startValueX);
		string startValueString = startval;

		if (!startValueString.empty())
		{
			// as I have to increment counters before each instance (to 
			//keep sub-list numbering from advancing too early, set startValue one lower;
			startValue = helper->convertToInt(startValueString) - 1; 
		}

		counter = startValue;

	}

	DOMElement *levelTextNode = helper->SelectSingleNode(doc, levelNode, "//w:lvlText");

	if (levelTextNode != NULL)
	{
		levelText = helper->GetAttributeValue(levelTextNode, ValAttrName);
	}

	DOMElement *fontNode = helper->SelectSingleNode(doc, levelNode, "//w:rFonts");

	if (fontNode != NULL)
	{
		font = helper->GetAttributeValue(fontNode, "w:hAnsi");
	}

	DOMElement *enumTypeNode = helper->SelectSingleNode(doc, levelNode, "//w:numFm");

	if (enumTypeNode != NULL)
	{
		XMLCh *type = helper->GetAttributeValue(enumTypeNode, ValAttrName);
		const XMLCh *bullet = XMLString::transcode("bullet");

		// w:numFmt="bullet" indicates a bulleted list
		isBullet = (XMLString::compareString(type, bullet) == 0);		
	}
}

ListLevel::ListLevel(const ListLevel &masterCopy)
{
	id = masterCopy.id;
	levelText = masterCopy.levelText;
	startValue = masterCopy.startValue;
	counter = startValue;
	font = masterCopy.font;
	isBullet = masterCopy.isBullet;
}

void ListLevel::SetOverrides(xercesc::DOMDocument *doc, DOMElement *levelNode)
{
	XMLHelper *helper = XMLHelper::getInstance();
	char* ValAttrName = "w:val";

	DOMElement *startValueNode = helper->SelectSingleNode(doc, levelNode, "//w:start");

	if (startValueNode != NULL)
	{
		XMLCh *startValueX = helper->GetAttributeValue(startValueNode, ValAttrName);
		char *startval = XMLString::transcode(startValueX);
		string startValueString = startval;

		// as I have to increment counters before each instance (to keep sub-list 
		// numbering from advancing too early, set startValue one lower
		if (!startValueString.empty())
		{
			// as I have to increment counters before each instance (to 
			//keep sub-list numbering from advancing too early, set startValue one lower;
			startValue = helper->convertToInt(startValueString) - 1; 
		}
//		XMLString::release(&startValueX);
	}

	counter = startValue;

	DOMElement *levelTextNode = helper->SelectSingleNode(doc, levelNode, "//w:lvlText");

	if (levelTextNode != NULL)
	{
		levelText = helper->GetAttributeValue(levelTextNode, ValAttrName);
	}

	DOMElement *fontNode = helper->SelectSingleNode(doc, levelNode, "//w:rFonts");

	if (fontNode != NULL)
	{
		font = helper->GetAttributeValue(fontNode, "w:hAnsi");
	}

	DOMElement *enumTypeNode = helper->SelectSingleNode(doc, levelNode, "//w:numFmt");

	if (enumTypeNode != NULL)
	{
		XMLCh *type = helper->GetAttributeValue(enumTypeNode, ValAttrName);
		const XMLCh *bullet = XMLString::transcode("bullet");

		// w:numFmt="bullet" indicates a bulleted list
		isBullet = (XMLString::compareString(type, bullet) == 0);		
	}
}

AbstractListNumberingDefinition::AbstractListNumberingDefinition()
{
	
}

AbstractListNumberingDefinition::AbstractListNumberingDefinition(xercesc::DOMDocument *doc, DOMElement *abstractNumNode)
{
	XMLHelper *helper = XMLHelper::getInstance();
	vector<DOMElement*>::iterator iter;
	char* ValAttrName = "w:val";
	XMLCh *abstractNumString = helper->GetAttributeValue(abstractNumNode, "w:abstractNumId");

	if (abstractNumString != NULL)
	{
		abstractNumDefId = abstractNumString;

		readListLevelsFromAbsNode(doc, abstractNumNode);

		// find out whether there is a linked abstractNum definition that this needs to be populated from later on
		DOMElement *linkedStyleNode = helper->SelectSingleNode(doc, abstractNumNode, "//w:numStyleLink");

		if (linkedStyleNode != NULL)
		{
			linkedStyleId = helper->GetAttributeValue(linkedStyleNode, ValAttrName);
		}
		else
		{
			linkedStyleId = NULL;
		}
	}
}

void AbstractListNumberingDefinition::UpdateDefinitionFromLinkedStyle(xercesc::DOMDocument *doc, DOMElement *linkedNode)
{
	if (linkedStyleId == NULL)
		return;

	readListLevelsFromAbsNode(doc, linkedNode);
}

void AbstractListNumberingDefinition::readListLevelsFromAbsNode(xercesc::DOMDocument *doc, DOMElement *absNumNode)
{
	XMLHelper *helper = XMLHelper::getInstance();
	vector<DOMElement*> *levelNodes = helper->ParseMinimalXPath(doc, absNumNode, "w:lvl");
	DOMElement *levelNode;

	// loop through the levels it defines and instantiate those
	vector<DOMElement*>::iterator iter = levelNodes->begin();

	for(int i = 0; i < levelNodes->size(); i++)
	{
		levelNode = iter[i];

		ListLevel level(doc, absNumNode);

		listLevels.insert(std::pair<XMLCh*,ListLevel>(level.id, level));
	}		
}

ListNumberingDefinition::ListNumberingDefinition()
{
}

ListNumberingDefinition::ListNumberingDefinition(xercesc::DOMDocument *doc, DOMElement *numNode, map<XMLCh*, AbstractListNumberingDefinition> abstractListDefinitions)
{
	XMLHelper *helper = XMLHelper::getInstance();
	char* ValAttrName = "w:val";


	listNumberId = helper->GetAttributeValue(numNode, "w:numId");

	DOMElement *abstractNumNode = helper->SelectSingleNode(doc, numNode, "//w:abstractNumId");

	if (abstractNumNode != NULL)
	{
		abstractListDefinition = abstractListDefinitions[helper->GetAttributeValue(abstractNumNode, ValAttrName)];

		// initialize the levels to the same as the template ("abstract") list level
		levels = abstractListDefinition.listLevels;

		// propagate the level overrides into the current list number level definition
		vector<DOMElement*> *levelOverrideNodes = helper->ParseMinimalXPath(doc, numNode, "//w:lvlOverride");

		if (levelOverrideNodes->size() > 0)
		{
			vector<DOMElement*>::iterator iter = levelOverrideNodes->begin();
			DOMElement *overrideNode, *node;

			for(int i=0; i < levelOverrideNodes->size(); i++)
			{
				overrideNode = iter[i];

				node = helper->SelectSingleNode(doc, overrideNode, "//w:lvl");
				if (node != NULL)
				{
					XMLCh *overrideLevelId = helper->GetAttributeValue(node, "w:ilvl");

					if (overrideLevelId != NULL)
					{
						levels[overrideLevelId].SetOverrides(doc,node);
					}
				}
			}
		}
	}
}

	

/// <summary>
/// increment the occurrence count of the specified level, reset the occurrence count of derived levels
/// </summary>
/// <param name="level"></param>
void ListNumberingDefinition::IncrementCounter(XMLCh *level)
{
	XMLHelper *helper = XMLHelper::getInstance();
	levels[level].ListLevelIncrementCounter();

	// here's a bit where the decision to use strings as level IDs was bad - 
	//I need to loop through the derived levels and reset their counters
	int levelNumber = helper->convertToInt(level) + 1;
	XMLCh *levelString = XMLString::transcode(helper->convertToString(levelNumber));

	ListLevel *templevel = &levels[levelString];

	while (templevel != NULL)
	{			
		templevel->ResetCounter();
		levelNumber++;
		levelString = XMLString::transcode(helper->convertToString(levelNumber));
		templevel = &levels[levelString];
	}
}



/// <summary>
/// returns a string containing the current state of the counters, up to the indicated level
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
XMLCh* ListNumberingDefinition::GetCurrentNumberString(XMLCh* level)
{
	XMLHelper *helper = XMLHelper::getInstance();
	string formatString = helper->convertToString(levels[level].levelText);

	string result;		
	string temp;				


	for (int i = 0; i < formatString.size(); i++)
	{
		temp = formatString.substr(i, 1);

		if (temp.compare("%") == 0)
		{
			if (i < formatString.size() - 1)
			{
				string formatStringLevel = formatString.substr(i + 1, 1);
				// as it turns out, in the format string, the level is 1-based					
				int levelId = helper->convertToInt(formatStringLevel) - 1;
				ListLevel *temp = &levels[helper->convertToXMLCh(levelId)];					
				result.append(helper->convertToString(temp->counter));
				i++;
			}
		}
		else
		{
			result.append(temp);
		}
	}	

	return helper->convertToXMLCh(temp);
}

/// <summary>
/// retrieve the font name that was specified for the list string
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
XMLCh* ListNumberingDefinition::GetFont(XMLCh *level)
{
	return levels[level].font;
}

/// <summary>
/// retrieve whether the level was a bullet list type
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
bool ListNumberingDefinition::IsBullet(XMLCh *level)
{
	return levels[level].isBullet;
}

/// <summary>
/// returns whether the specific level ID exists - in testing we've seen some referential integrity issues due to Word bugs
/// </summary>
/// <param name="level">
/// </param>
/// <returns>
/// </returns>
/// <id guid="b94c13b8-7273-4f6a-927b-178d685fbe0f" />
/// <owner alias="ROrleth" />
bool ListNumberingDefinition::LevelExists(XMLCh *level)
{
	ListLevel *def = &levels[level];
	return (def == NULL?false:true);
}



void WordXmlPicture::ReadStandardAttributes(DOMElement *fromNode)
{
	XMLHelper *helper = XMLHelper::getInstance();

	id = helper->GetAttributeValue(fromNode, "id");
	type = helper->GetAttributeValue(fromNode, "type");
	alt = helper->GetAttributeValue(fromNode, "alt");
	style = helper->GetAttributeValue(fromNode, "style");	
}

void WordXmlPicture::ReadLinkAttributes(DOMElement *fromNode)
{
	XMLHelper *helper = XMLHelper::getInstance();
	targetFrame = helper->GetAttributeValue(fromNode, "tgtFrame");
	tooltip = helper->GetAttributeValue(fromNode, "tooltip");		
}

void WordXmlPicture::ReadSizeAttributes(DOMElement *fromNode)
{
	XMLHelper *helper = XMLHelper::getInstance();
	XMLCh *temp = NULL;
	temp = helper->GetAttributeValue(fromNode, "cx");
	
	if (XMLString::stringLen(temp) > 0)
	{
		SetWidth(helper->convertToInt(temp)/ ExtentToPixelConversionFactor);
	}
	temp = helper->GetAttributeValue(fromNode, "cy");
	if (temp != NULL)
	{
		SetHeight(helper->convertToInt(temp) / ExtentToPixelConversionFactor);
	}
}

// Width in pixels	
void WordXmlPicture::SetWidth(int val)
{
	widthSet = true;
	width = (float)val * 1.333;
}	

// Height in pixels
void WordXmlPicture::SetHeight(int val)
{
	heightSet = true;
	height = (float)val * 1.333;
}	

void XMLHelper::UpdateImageNames(map<const XMLCh*, const XMLCh*> &imgmap, string filename, const char* tempFolderPath)
{
      map<const XMLCh*, const XMLCh*>::iterator iter = imgmap.begin();
      XMLCh *key, *val;
      string val_temp, val_new, val_old;
	  string path_old, path_new;
      string val_pref = "/media/";
      val_pref.append(filename);
      val_pref.append("_");

      while(iter != imgmap.end())
      {
			path_old = tempFolderPath;
			path_old.append("/word/");
			path_new = tempFolderPath;
			path_new.append("/word/");

            key = const_cast<XMLCh*>(iter->first);
            val = const_cast<XMLCh*>(iter->second);
            val_old = convertToString(val);

            val_temp = val_old.substr(6);
            val_new = val_pref;
            val_new.append(val_temp);

			path_old.append(val_old);
			path_new.append(val_new);
			rename(path_old.c_str(), path_new.c_str());

            iter->second = convertToXMLCh(val_new);
            iter++;
      }
}
